{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"id": "89cf2628",
"metadata": {},
"source": [
"# Asymmetric Calculation Example\n",
"\n",
"In this notebook we will walk through an example of asymmetric calculation using `power-grid-model`. \n",
"The following points are covered\n",
" * Construction of the model\n",
" * Run asymmetric power flow calculation once, and its relevant function arguments\n",
" * Run asymmetric power flow in batch calculations, and its relevant function arguments\n",
" * Run state estimation once, and its relevant function arguments\n",
"\n",
"This notebook serves as an example of how to use the Python API. For detailed API documentation, refer to\n",
"[Python API reference](https://power-grid-model.readthedocs.io/en/stable/api_reference/python-api-reference.html)\n",
"and [Native Data Interface](https://power-grid-model.readthedocs.io/en/stable/advanced_documentation/native-data-interface.html).\n",
"\n",
"\n",
"## Example Network\n",
"\n",
"We use a simple network with 3 nodes, 1 source, 3 lines, and 2 loads (1 symmetric load, 1 asymmetric load). As shown below:\n",
"\n",
"```\n",
" -------------------line_8-------------------\n",
" | |\n",
"node_1 ---line_3--- node_2 ----line_5---- node_6\n",
" | | |\n",
"source_10 sym_load_4 asym_load_7\n",
"```\n",
"\n",
"The 3 nodes are connected in a triangular way by 3 lines.\n",
"\n",
"**NOTE: load_7 is asymmetric in this case.**"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "ae11dc9a",
"metadata": {},
"outputs": [],
"source": [
"# some basic imports\n",
"import numpy as np\n",
"import pandas as pd\n",
"\n",
"from power_grid_model import (\n",
" AttributeType,\n",
" CalculationMethod,\n",
" CalculationType,\n",
" ComponentType,\n",
" DatasetType,\n",
" LoadGenType,\n",
" MeasuredTerminalType,\n",
" PowerGridModel,\n",
" initialize_array,\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "f983cef7",
"metadata": {},
"source": [
"## Power Flow Calculation\n",
"### Input Dataset\n",
"\n",
"We create input dataset by using the helper function `initialize_array`.\n",
"Note the units of all input are standard SI unit without any prefix,\n",
"i.e. the unit of voltage is volt (V), not kV.\n",
"\n",
"Please refer [Components](https://power-grid-model.readthedocs.io/en/stable/user_manual/components.html) for detailed explanation of all component types and their input/output attributes. \n",
"\n",
"**NOTE: The required attributes of each components can be different for asymmetric calculations.**"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "6f008736",
"metadata": {},
"outputs": [],
"source": [
"# node\n",
"node = initialize_array(DatasetType.input, ComponentType.node, 3)\n",
"node[AttributeType.id] = np.array([1, 2, 6])\n",
"node[AttributeType.u_rated] = [10.5e3, 10.5e3, 10.5e3]\n",
"\n",
"# line\n",
"line = initialize_array(DatasetType.input, ComponentType.line, 3)\n",
"line[AttributeType.id] = [3, 5, 8]\n",
"line[AttributeType.from_node] = [1, 2, 1]\n",
"line[AttributeType.to_node] = [2, 6, 6]\n",
"line[AttributeType.from_status] = [1, 1, 1]\n",
"line[AttributeType.to_status] = [1, 1, 1]\n",
"line[AttributeType.r1] = [0.25, 0.25, 0.25]\n",
"line[AttributeType.x1] = [0.2, 0.2, 0.2]\n",
"line[AttributeType.c1] = [10e-6, 10e-6, 10e-6]\n",
"line[AttributeType.tan1] = [0.0, 0.0, 0.0]\n",
"line[AttributeType.i_n] = [1000, 1000, 1000]\n",
"line[AttributeType.r0] = [0.25, 0.25, 0.25]\n",
"line[AttributeType.x0] = [0.2, 0.2, 0.2]\n",
"line[AttributeType.c0] = [10e-6, 10e-6, 10e-6]\n",
"line[AttributeType.tan0] = [0, 0, 0]\n",
"\n",
"# sym load\n",
"sym_load = initialize_array(DatasetType.input, ComponentType.sym_load, 1)\n",
"sym_load[AttributeType.id] = [4]\n",
"sym_load[AttributeType.node] = [2]\n",
"sym_load[AttributeType.status] = [1]\n",
"sym_load[AttributeType.type] = [LoadGenType.const_power]\n",
"sym_load[AttributeType.p_specified] = [20e6]\n",
"sym_load[AttributeType.q_specified] = [5e6]\n",
"\n",
"# asym load\n",
"asym_load = initialize_array(DatasetType.input, ComponentType.asym_load, 1)\n",
"asym_load[AttributeType.id] = [7]\n",
"asym_load[AttributeType.node] = [6]\n",
"asym_load[AttributeType.status] = [1]\n",
"asym_load[AttributeType.type] = [LoadGenType.const_power]\n",
"asym_load[AttributeType.p_specified] = [[10e6, 20e6, 0]] # the 3 phases may have different loads\n",
"asym_load[AttributeType.q_specified] = [[0, 8e6, 2e6]] # the 3 phases may have different loads\n",
"\n",
"# source\n",
"source = initialize_array(DatasetType.input, ComponentType.source, 1)\n",
"source[AttributeType.id] = [10]\n",
"source[AttributeType.node] = [1]\n",
"source[AttributeType.status] = [1]\n",
"source[AttributeType.u_ref] = [1.0]\n",
"\n",
"# all\n",
"asym_input_data = {\n",
" ComponentType.node: node,\n",
" ComponentType.line: line,\n",
" ComponentType.sym_load: sym_load,\n",
" ComponentType.asym_load: asym_load,\n",
" ComponentType.source: source,\n",
"}"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "e3605c3e",
"metadata": {},
"source": [
"### One-time Asymmetric Power Flow Calculation\n",
"\n",
"You can call the method `calculate_power_flow` to do a one-time calculation based on the current network data in the model. In this case you should not specify the argument `update_data` as it is used for batch calculation.\n",
"\n",
"**NOTE: For asymmetric calculations, the argument `symmetric` of `calculate_power_flow` and `assert_valid_input_data` should both be set to False.**"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "44c2de63",
"metadata": {},
"outputs": [],
"source": [
"# Validation (optional)\n",
"from power_grid_model.validation import assert_valid_input_data\n",
"\n",
"assert_valid_input_data(input_data=asym_input_data, calculation_type=CalculationType.power_flow, symmetric=False)\n",
"\n",
"# Construction\n",
"asym_model = PowerGridModel(asym_input_data)\n",
"\n",
"# One-time Asymmetric Power Flow Calculation\n",
"asym_result = asym_model.calculate_power_flow(\n",
" symmetric=False, # This enables asymmetric calculations\n",
" error_tolerance=1e-8,\n",
" max_iterations=20,\n",
" calculation_method=CalculationMethod.newton_raphson,\n",
")"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "d08aaf45",
"metadata": {},
"source": [
"We can print a result dataset of node by converting the array to dataframe and refering a specific attribute. In asymmetric calculations, the results of each phase is presented."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "a581a36e",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"------node voltage result------\n",
" 0 1 2\n",
"0 6054.809261 6033.110279 6054.482030\n",
"1 5669.760420 5342.536191 5804.933216\n",
"2 5638.571767 5028.415453 5897.375970\n",
"------node angle result------\n",
" 0 1 2\n",
"0 -0.005248 -2.103279 2.092430\n",
"1 -0.043049 -2.143908 2.078903\n",
"2 -0.054168 -2.157686 2.092568\n"
]
}
],
"source": [
"print(\"------node voltage result------\")\n",
"print(pd.DataFrame(asym_result[ComponentType.node][AttributeType.u]))\n",
"print(\"------node angle result------\")\n",
"print(pd.DataFrame(asym_result[ComponentType.node][AttributeType.u_angle]))"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "4f59d0f5",
"metadata": {},
"source": [
"## Batch Asymmetric Power Flow Calculation\n",
"\n",
"As for asymmetric calculations (see the Power Flow Example), we can use the same method `calculate_power_flow` to calculate a number of asymmetric scenarios in one go. To do this, you need to supply an `update_data` argument. This argument contains a dictionary of 3D update arrays (one array per component type per phase).\n",
"\n",
"The model uses the current data as the base scenario. For each individual calculation, the model applies each mutation to the base scenario and calculates the power flow.\n",
"\n",
"**NOTE: after the batch calculation, the original model will be kept unchanged. Internally the program copies the original model to multiple batch models for the calculation.**"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "56850333",
"metadata": {},
"source": [
"### Independent Batch Dataset\n",
"\n",
"There are two ways to specify the mutations. For each scenario:\n",
"\n",
"* only specify the objects that are changed in this scenario; or\n",
"* specify all objects that are changed in one or multiple scenarios.\n",
"\n",
"The latter is called independent batch dataset. Because all relevant objects are specified in each batch, different choices regarding performance optimization may be made in either case.\n",
"\n",
"In general, the following is advised:\n",
"\n",
"* Use the non-independent batch dataset approach whenever few parameters change per scenario, but the batch samples many different components, e.g. during N-1 tests.\n",
"* Use the independent batch dataset approach when a dense sampling of the parameter space is desired for relatively a few different components, e.g. during time series power flow calculation\n",
"\n",
"See also [performance guide](https://power-grid-model.readthedocs.io/en/stable/user_manual/performance-guide.html) for the latest recommendations."
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "93a22edb",
"metadata": {},
"source": [
"The following code presented here creates a load profile with 10 timestamps for `load_7`. For N-1 scenario we refer to the [Power Flow Example](./Power%20Flow%20Example.ipynb)."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "42d5cd8f",
"metadata": {},
"outputs": [],
"source": [
"# note the shape of the array, 10 scenarios, 1 objects (asymmetric load_7)\n",
"load_profile = initialize_array(DatasetType.update, ComponentType.asym_load, (10, 1))\n",
"\n",
"# this is a scale of asym_load from 0% to 100%------------------\n",
"# the array is an (10, 1, 3) shape, which shows (scenario, object, phase).\n",
"# Users can always customize the load_profile in different ways.\n",
"load_profile[AttributeType.id] = [7]\n",
"load_profile[AttributeType.p_specified] = [10e6, 20e6, 0] * np.linspace(0, 1, 10).reshape(-1, 1, 1)\n",
"\n",
"time_series_mutation = {ComponentType.asym_load: load_profile}"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "363aa67d",
"metadata": {},
"source": [
"We can calculate the time series and print the current of the lines."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "4e25006f",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"# Validation (optional)\n",
"from power_grid_model.validation import assert_valid_batch_data\n",
"\n",
"assert_valid_batch_data(\n",
" input_data=asym_input_data,\n",
" update_data=time_series_mutation,\n",
" symmetric=False,\n",
" calculation_type=CalculationType.power_flow,\n",
")\n",
"\n",
"# Batch Asymmetric Power Flow Calculation\n",
"output_data = asym_model.calculate_power_flow(update_data=time_series_mutation, symmetric=False)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "c9d23a92",
"metadata": {},
"source": [
"#### Accessing batch data\n",
"\n",
"It may be a bit unintuitive to read the `output_data` or `update_data` of a component directly as they are a dictionary of 4 dimension data, i.e., $ids \\times batches \\times attributes \\times phases$. Remember that the `output_data` or `update_data` are a dictionary of numpy structured arrays. Hence the component should be indexed first. The index that follows can be [indexed with numpy structured arrays](https://numpy.org/doc/stable/user/basics.rec.html#indexing-structured-arrays).\n",
"\n",
"To read the result of a single batch, e.g. 1st batch,"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "afccf7a2",
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" 0 | \n",
" 1 | \n",
" 2 | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" 4.596683e+06 | \n",
" 4.779610e+06 | \n",
" 4.620493e+06 | \n",
"
\n",
" \n",
" | 1 | \n",
" -2.222542e+06 | \n",
" -2.146006e+06 | \n",
" -2.213746e+06 | \n",
"
\n",
" \n",
" | 2 | \n",
" 2.298865e+06 | \n",
" 2.512050e+06 | \n",
" 2.310381e+06 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 0 1 2\n",
"0 4.596683e+06 4.779610e+06 4.620493e+06\n",
"1 -2.222542e+06 -2.146006e+06 -2.213746e+06\n",
"2 2.298865e+06 2.512050e+06 2.310381e+06"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display(pd.DataFrame(output_data[ComponentType.line][AttributeType.p_from][0]))"
]
},
{
"attachments": {},
"cell_type": "markdown",
"id": "6d9f285a",
"metadata": {},
"source": [
"Or maybe we wish to find result of a single component, (e.g., 1st line) in all batches"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "9af1be38",
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" 0 | \n",
" 1 | \n",
" 2 | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" 778.966268 | \n",
" 1011.794128 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 1 | \n",
" 842.493451 | \n",
" 1121.320184 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 2 | \n",
" 906.985877 | \n",
" 1239.243741 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 3 | \n",
" 972.433947 | \n",
" 1364.771826 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 4 | \n",
" 1038.839396 | \n",
" 1497.459012 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 5 | \n",
" 1106.212978 | \n",
" 1637.140796 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 6 | \n",
" 1174.572956 | \n",
" 1783.892394 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 7 | \n",
" 1243.944125 | \n",
" 1938.010800 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 8 | \n",
" 1314.357217 | \n",
" 2100.018933 | \n",
" 815.316511 | \n",
"
\n",
" \n",
" | 9 | \n",
" 1385.848583 | \n",
" 2270.693567 | \n",
" 815.316511 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 0 1 2\n",
"0 778.966268 1011.794128 815.316511\n",
"1 842.493451 1121.320184 815.316511\n",
"2 906.985877 1239.243741 815.316511\n",
"3 972.433947 1364.771826 815.316511\n",
"4 1038.839396 1497.459012 815.316511\n",
"5 1106.212978 1637.140796 815.316511\n",
"6 1174.572956 1783.892394 815.316511\n",
"7 1243.944125 1938.010800 815.316511\n",
"8 1314.357217 2100.018933 815.316511\n",
"9 1385.848583 2270.693567 815.316511"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display(pd.DataFrame(output_data[ComponentType.line][AttributeType.i_from][:, 0]))"
]
},
{
"cell_type": "markdown",
"id": "88950d8a-6cf2-4f4b-b6ec-0cd02fd19b29",
"metadata": {},
"source": [
"## Asymmetric State Estimation\n",
"### Input Dataset for State Estimation\n",
"\n",
"**NOTE: Asymmetric voltage/power sensors should be applied to (at least) asymmetric components.**\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "f97758a1-c5cc-4410-ad22-bf7612e9486d",
"metadata": {},
"outputs": [],
"source": [
"# sym voltage sensor\n",
"sym_voltage_sensor = initialize_array(DatasetType.input, ComponentType.sym_voltage_sensor, 2)\n",
"sym_voltage_sensor[AttributeType.id] = [11, 12]\n",
"sym_voltage_sensor[AttributeType.measured_object] = [1, 2]\n",
"sym_voltage_sensor[AttributeType.u_sigma] = [100, 10]\n",
"sym_voltage_sensor[AttributeType.u_measured] = [6000, 5500]\n",
"\n",
"# asym voltage sensor\n",
"asym_voltage_sensor = initialize_array(DatasetType.input, ComponentType.asym_voltage_sensor, 1)\n",
"asym_voltage_sensor[AttributeType.id] = [13]\n",
"asym_voltage_sensor[AttributeType.measured_object] = [6]\n",
"asym_voltage_sensor[AttributeType.u_sigma] = [100]\n",
"asym_voltage_sensor[AttributeType.u_measured] = [[5640, 5000, 6000]]\n",
"\n",
"\n",
"# sym power sensor\n",
"sym_power_sensor = initialize_array(DatasetType.input, ComponentType.sym_power_sensor, 7)\n",
"sym_power_sensor[AttributeType.id] = [14, 15, 16, 17, 18, 19, 20]\n",
"sym_power_sensor[AttributeType.measured_object] = [3, 3, 5, 5, 8, 8, 4]\n",
"sym_power_sensor[AttributeType.measured_terminal_type] = [\n",
" MeasuredTerminalType.branch_from,\n",
" MeasuredTerminalType.branch_to,\n",
" MeasuredTerminalType.branch_from,\n",
" MeasuredTerminalType.branch_to,\n",
" MeasuredTerminalType.branch_from,\n",
" MeasuredTerminalType.branch_to,\n",
" MeasuredTerminalType.load,\n",
"]\n",
"sym_power_sensor[AttributeType.power_sigma] = [1.0e5, 1.0e4, 1.0e5, 1.0e4, 1.0e4, 1.0e5, 1.0e5]\n",
"sym_power_sensor[AttributeType.p_measured] = [10e6, -20e6, 4e6, -4e6, 25e6, -15e6, 20e6]\n",
"sym_power_sensor[AttributeType.q_measured] = [5e6, -7e6, 2e6, -2e6, 5e6, -5e6, 5e6]\n",
"\n",
"# asym power sensor\n",
"asym_power_sensor = initialize_array(DatasetType.input, ComponentType.asym_power_sensor, 1)\n",
"asym_power_sensor[AttributeType.id] = [21]\n",
"asym_power_sensor[AttributeType.measured_object] = [6]\n",
"asym_power_sensor[AttributeType.measured_terminal_type] = [MeasuredTerminalType.node]\n",
"asym_power_sensor[AttributeType.power_sigma] = [1.0e5]\n",
"asym_power_sensor[AttributeType.p_measured] = [[10e6, 20e6, 0]]\n",
"asym_power_sensor[AttributeType.q_measured] = [[0, 8e6, 2e6]]\n",
"\n",
"# all\n",
"asym_input_data = {\n",
" ComponentType.node: node,\n",
" ComponentType.line: line,\n",
" ComponentType.sym_load: sym_load,\n",
" ComponentType.asym_load: asym_load,\n",
" ComponentType.source: source,\n",
" ComponentType.sym_voltage_sensor: sym_voltage_sensor,\n",
" ComponentType.asym_voltage_sensor: asym_voltage_sensor,\n",
" ComponentType.sym_power_sensor: sym_power_sensor,\n",
" ComponentType.asym_power_sensor: asym_power_sensor,\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "292e990b-093a-475d-b6e3-3952bb4e2880",
"metadata": {},
"source": [
"### One-time Asymmetric State Estimation"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "0540ffdb-006e-48d5-b055-3af6979d586b",
"metadata": {},
"outputs": [],
"source": [
"# Validation(optional)\n",
"from power_grid_model.validation import assert_valid_input_data\n",
"\n",
"assert_valid_input_data(input_data=asym_input_data, calculation_type=CalculationType.state_estimation, symmetric=False)\n",
"\n",
"# Construction\n",
"asym_model = PowerGridModel(asym_input_data)\n",
"\n",
"# Perform one-time asymmetric state estimation calculation\n",
"asym_result = asym_model.calculate_state_estimation(symmetric=False, error_tolerance=1e-3)"
]
},
{
"cell_type": "markdown",
"id": "8532a098-3377-4673-8783-d62a4e6347cd",
"metadata": {},
"source": [
"We can also print a result dataset of `node` by converting the array to dataframe."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "46b82eb3-28e5-48a9-a6c3-3247ef8fdfe0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"------node voltage result------\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" 0 | \n",
" 1 | \n",
" 2 | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" -456.470670 | \n",
" -453.494614 | \n",
" -457.679045 | \n",
"
\n",
" \n",
" | 1 | \n",
" -96.057029 | \n",
" -96.031740 | \n",
" -95.861330 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 0 1 2\n",
"0 -456.470670 -453.494614 -457.679045\n",
"1 -96.057029 -96.031740 -95.861330"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"------sym_load result------\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" 0 | \n",
" 1 | \n",
" 2 | \n",
"
\n",
" \n",
" \n",
" \n",
" | 0 | \n",
" -4.822819e+06 | \n",
" -4.778850e+06 | \n",
" -4.842920e+06 | \n",
"
\n",
" \n",
" | 1 | \n",
" 2.883705e+05 | \n",
" 2.554854e+05 | \n",
" 3.032475e+05 | \n",
"
\n",
" \n",
" | 2 | \n",
" 4.827303e+05 | \n",
" 4.255387e+05 | \n",
" 5.069975e+05 | \n",
"
\n",
" \n",
" | 3 | \n",
" -5.005799e+05 | \n",
" -4.454748e+05 | \n",
" -5.240727e+05 | \n",
"
\n",
" \n",
" | 4 | \n",
" -8.573380e+05 | \n",
" -8.781561e+05 | \n",
" -8.504175e+05 | \n",
"
\n",
" \n",
" | 5 | \n",
" 2.711764e+06 | \n",
" 2.721883e+06 | \n",
" 2.709151e+06 | \n",
"
\n",
" \n",
" | 6 | \n",
" 5.622326e+05 | \n",
" 6.523093e+05 | \n",
" 5.230883e+05 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" 0 1 2\n",
"0 -4.822819e+06 -4.778850e+06 -4.842920e+06\n",
"1 2.883705e+05 2.554854e+05 3.032475e+05\n",
"2 4.827303e+05 4.255387e+05 5.069975e+05\n",
"3 -5.005799e+05 -4.454748e+05 -5.240727e+05\n",
"4 -8.573380e+05 -8.781561e+05 -8.504175e+05\n",
"5 2.711764e+06 2.721883e+06 2.709151e+06\n",
"6 5.622326e+05 6.523093e+05 5.230883e+05"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"print(\"------node voltage result------\")\n",
"display(pd.DataFrame(asym_result[ComponentType.sym_voltage_sensor][AttributeType.u_residual]))\n",
"\n",
"print(\"------sym_load result------\")\n",
"display(pd.DataFrame(asym_result[ComponentType.sym_power_sensor][AttributeType.p_residual]))"
]
},
{
"cell_type": "markdown",
"id": "9330460f-186c-4e44-8a8a-012f99607530",
"metadata": {},
"source": [
"For the observability and batch calculation of state estimation, we refer to the [State Estimation Example](./State%20Estimation%20Example.ipynb)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "power-grid-model",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.14.3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}